<template>
  <!--
    节点面板列表，遍历 list 渲染每个可拖拽的节点类型
    每个 li 支持拖拽，拖拽时会携带节点的配置信息
  -->
  <ul>
    <li
      v-for="(item,index) in list"
      :key="index"
      class="getItem"
      :data-shape="item.shape"
      :data-type="item.type"
      :data-size="item.size"
      draggable
      @dragstart="handleDragstart"
      @dragend="handleDragEnd($event,item)"
    >
      <!-- 节点图标 -->
      <span class="pannel-type-icon" :style="{background:'url('+item.image+')'}"></span>
      {{item.name}}
    </li>
  </ul>
</template>

<script>
import eventBus from "@/utils/eventBus"; // 引入全局事件总线
import okSvg from "@/assets/icons/ok.svg"; // 状态图标
import bgImg from "@/assets/bg.jpg"; // 背景图片
export default {
  data() {
    return {
      page: null, // 当前页面对象
      command: null, // 命令对象
      offsetX: 0, // 拖拽时鼠标相对 li 的 X 偏移
      offsetY: 0, // 拖拽时鼠标相对 li 的 Y 偏移
      // 节点类型列表，每个对象描述一个可拖拽节点的配置
      list: [
        {
          name: "测试节点", // 节点名称
          label: "测试节点", // 节点标签
          size: "170*34", // 节点尺寸
          type: "node", // 类型
          x: 0,
          y: 0,
          shape: "customNode", // 使用的自定义节点类型
          color: "#1890ff", // 侧边色条颜色
          image:
            "https://gw.alipayobjects.com/zos/rmsportal/czNEJAmyDpclFaSucYWB.svg", // 图标
          stateImage: okSvg, // 状态图标
          inPoints: [[0, 0.5]], // 输入锚点
          outPoints: [[1, 0.5]] // 输出锚点
        },
        // 其它节点类型配置 ...
        {
          name: "背景图片节点",
          label: "背景图片节点",
          size: "170*34",
          type: "node",
          x: 0,
          y: 0,
          shape: "customNode",
          color: "#1890ff",
          image:
            "https://gw.alipayobjects.com/zos/rmsportal/czNEJAmyDpclFaSucYWB.svg",
          stateImage: okSvg,
          backImage: bgImg, // 背景图片
          inPoints: [[0, 0.5]],
          outPoints: [[1, 0.5]]
        },
        {
          name: "双输出节点",
          label: "双输出节点",
          size: "170*34",
          type: "node",
          x: 0,
          y: 0,
          shape: "customNode",
          color: "#1890ff",
          image:
            "https://gw.alipayobjects.com/zos/rmsportal/czNEJAmyDpclFaSucYWB.svg",
          stateImage: okSvg,
          inPoints: [[0, 0.5]],
          outPoints: [[1, 0.4], [1, 0.6]] // 多个输出锚点
        },
        {
          name: "大型节点",
          label: "大型节点",
          size: "340*34",
          type: "node",
          x: 0,
          y: 0,
          shape: "customNode",
          color: "#1890ff",
          image:
            "https://gw.alipayobjects.com/zos/rmsportal/czNEJAmyDpclFaSucYWB.svg",
          stateImage: okSvg,
          inPoints: [[0, 0.5]],
          outPoints: [[1, 0.5]]
        },
        {
          name: "动画开始节点",
          label: "动画开始",
          size: "170*34",
          type: "node",
          x: 0,
          y: 0,
          shape: "customNode",
          color: "#1890ff",
          image:
            "https://gw.alipayobjects.com/zos/rmsportal/czNEJAmyDpclFaSucYWB.svg",
          stateImage: okSvg,
          inPoints: [[0, 0.5]],
          outPoints: [[1, 0.5]],
          isDoingStart: true // 动画开始标记
        },
        {
          name: "动画结束节点",
          label: "动画结束",
          size: "170*34",
          type: "node",
          x: 0,
          y: 0,
          shape: "customNode",
          color: "#1890ff",
          image:
            "https://gw.alipayobjects.com/zos/rmsportal/czNEJAmyDpclFaSucYWB.svg",
          stateImage: okSvg,
          inPoints: [[0, 0.5]],
          outPoints: [[1, 0.5]],
          isDoingEnd: true // 动画结束标记
        }
      ]
    };
  },
  created() {
    this.bindEvent(); // 组件创建时绑定事件
  },
  methods: {
    // 拖拽开始，记录鼠标相对 li 的偏移
    handleDragstart(e) {
      this.offsetX = e.offsetX;
      this.offsetY = e.offsetY;
    },
    // 拖拽结束，计算节点应放置的位置并通过命令添加到画布
    handleDragEnd(e, item) {
      let data = {};
      Object.assign(data, item);
      data.offsetX = this.offsetX;
      data.offsetY = this.offsetY;
      if (this.page) {
        const graph = this.page.graph;
        // const size = e.target.dataset.size.split("*");
        const xy = graph.getPointByClient(e.x, e.y); // 将屏幕坐标转为画布坐标
        data.x = xy.x;
        data.y = xy.y;
        data.size = item.size.split("*"); // 转为数组
        data.type = "node";
        this.command.executeCommand("add", [data]); // 执行添加节点命令
      }
    },
    // 绑定 afterAddPage 事件，获取 page 和 command 实例
    bindEvent() {
      eventBus.$on("afterAddPage", page => {
        this.page = page;
        this.command = page.command;
      });
    }
  }
};
</script>

<style scoped>
/*
itempannel 组件样式，控制左侧面板的布局、背景、边框等
*/
.itempannel {
  height: 100%;
  position: absolute;
  left: 0px;
  z-index: 2;
  background: #f7f9fb;
  width: 200px;
  padding-top: 8px;
  border-right: 1px solid #e6e9ed;
}
.itempannel ul {
  padding: 0px;
  padding-left: 16px;
}
.itempannel li {
  color: rgba(0, 0, 0, 0.65);
  border-radius: 4px;
  width: 160px;
  height: 28px;
  line-height: 26px;
  padding-left: 8px;
  border: 1px solid rgba(0, 0, 0, 0);
  list-style-type: none;
}
.itempannel li:hover {
  background: white;
  border: 1px solid #ced4d9;
  cursor: move;
}

.itempannel .pannel-type-icon {
  width: 16px;
  height: 16px;
  display: inline-block;
  vertical-align: middle;
  margin-right: 8px;
}
</style>